import { Component } from 'cc'
import { ClickBindingOptions, PropertyBindingOptions, ZClickBinder, ZPropertyBinder } from '../binders'

/**
 * MVC中的控制器/视图控制器
 * 提供自动属性绑定和点击事件绑定功能
 */
export class ZController extends Component {
	/**
	 * 属性绑定配置
	 * 子类可以覆盖此属性来定义需要绑定的节点和组件
	 *
	 * @example
	 * protected propertyBindings = {
	 *   // 简单节点绑定
	 *   container: 'UI/Container',
	 *
	 *   // 组件绑定
	 *   titleLabel: { path: 'UI/Title', component: Label },
	 *   scoreLabel: { path: 'UI/Score', component: Label, optional: true }
	 * };
	 */
	protected propertyBindings: Record<string, string | ({ path: string } & PropertyBindingOptions)> = {}

	/**
	 * 点击事件绑定配置
	 * 子类可以覆盖此属性来定义需要绑定的点击事件
	 *
	 * @example
	 * protected clickBindings = {
	 *   // 简单点击绑定，方法名: 节点路径
	 *   onStartButtonClick: 'UI/StartButton',
	 *
	 *   // 带选项的点击绑定
	 *   onSettingsButtonClick: {
	 *     path: 'UI/SettingsButton',
	 *     optional: true
	 *   },
	 *
	 *   // 自定义方法名
	 *   closeDialog: {
	 *     path: 'UI/CloseButton',
	 *     method: 'onCloseButtonClick'
	 *   }
	 * };
	 */
	protected clickBindings: Record<string, string | ({ path: string } & ClickBindingOptions)> = {}

	/** 属性绑定器实例 */
	private propertyBinder: ZPropertyBinder = null!

	/** 点击绑定器实例 */
	private clickBinder: ZClickBinder = null!

	constructor() {
		super()
	}

	/**
	 * 获取属性绑定器实例
	 * 可用于在子类中进行额外的手动绑定操作
	 * @protected
	 */
	protected getPropertyBinder(): ZPropertyBinder {
		return this.propertyBinder
	}

	/**
	 * 获取点击绑定器实例
	 * 可用于在子类中进行额外的手动绑定操作
	 * @protected
	 */
	protected getClickBinder(): ZClickBinder {
		return this.clickBinder
	}

	/**
	 * 生命周期：组件加载时
	 * 执行属性绑定和点击事件绑定，并调用子类的初始化方法
	 */
	onLoad() {
		// 创建绑定器
		this.propertyBinder = new ZPropertyBinder(this)
		this.clickBinder = new ZClickBinder(this)

		// 执行绑定
		this.bindProperties()
		this.bindClicks()

		// 调用子类的初始化方法
		this.onControllerLoad()
	}

	/**
	 * 执行属性绑定
	 * 处理 propertyBindings 中定义的所有绑定
	 * @protected
	 */
	protected bindProperties(): void {
		if (Object.keys(this.propertyBindings).length > 0) {
			this.propertyBinder.bindBatch(this.propertyBindings)
		}
	}

	/**
	 * 执行点击事件绑定
	 * 处理 clickBindings 中定义的所有绑定
	 * @protected
	 */
	protected bindClicks(): void {
		if (Object.keys(this.clickBindings).length > 0) {
			this.clickBinder.bindClicks(this.clickBindings)
		}
	}

	/**
	 * 控制器加载完成后调用
	 * 子类应该覆盖此方法而不是onLoad
	 * @protected
	 */
	protected onControllerLoad() {
		// 子类实现
	}
}
